package com.css.common.core.utils.yl;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @description:
 * @Title: RSACoder
 * @Author xlw
 * @Package com.test
 * @Date 2024/7/11 16:23
 */
public class RSACoder {

    public static final String KEY_ALGORITHM = "RSA";
    public final static String ALGORITHM_SHA256WITHRSA = "SHA256withRSA";
    private static final char[] HEXCHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    public static String generateSortStr(Map<String, Object> map, boolean allowValueNull) {
        List<String> keys = new ArrayList<>(map.size());
        for (String key : map.keySet()) {
            if ((!allowValueNull && (null == map.get(key) || "".equals(map.get(key))))
                    || "sign".equals(key)
                    || "signValue".equals(key)
                    || "sign_type".equals(key)) {
                continue;
            }
            keys.add(key);
        }
        Collections.sort(keys);
        StringBuilder sb = new StringBuilder();
        boolean isFirst = true;
        for (String key : keys) {
            Object obj = map.get(key);
            String rr;
            if (obj instanceof Integer || obj instanceof Double || obj instanceof BigDecimal || obj instanceof Float) {
                rr = String.valueOf(obj);
            } else if (obj instanceof String) {
                rr = (String) obj;
            } else {
                rr = JSONUtil.toJsonStr(obj);
            }
            if (isFirst) {
                sb.append(key).append("=").append(rr);
                isFirst = false;
                continue;
            }
            sb.append("&").append(key).append("=").append(rr);
        }
        return sb.toString();
    }

    public static byte[] decryptBASE64(String src) {
        sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();

        try {
            return decoder.decodeBuffer(src);
        } catch (Exception ex) {
            return null;
        }

    }

    public static String toHexString(byte[] b) {
        StringBuilder sb = new StringBuilder(b.length * 2);
        for (byte value : b) {
            sb.append(HEXCHAR[(value & 0xf0) >>> 4]);
            sb.append(HEXCHAR[value & 0x0f]);
        }
        return sb.toString();
    }

    public static String sign(byte[] rawData, String privateKey, String algorithm) throws Exception {
        byte[] keyBytes = decryptBASE64(privateKey);
        assert keyBytes != null;
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature instance = Signature.getInstance(algorithm);
        instance.initSign(priKey);
        instance.update(rawData);
        return toHexString(instance.sign());
    }

    public static byte[] encryptByPublicKey(byte[] data, String publicKey, int length, boolean isBc)
            throws Exception {
        byte[] keyBytes = decryptBASE64(publicKey);
        assert keyBytes != null;
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        // 对数据加密
        Cipher cipher;
        if (isBc) {
            Security.addProvider(new BouncyCastleProvider());
            cipher = Cipher.getInstance(keyFactory.getAlgorithm(), "BC");
        } else {
            cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        }
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > length) {
                cache = cipher.doFinal(data, offSet, length);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * length;
        }
        byte[] encryptData = out.toByteArray();
        out.close();
        return encryptData;
    }

    public static byte[] toBytes(String s) {
        byte[] bytes;
        bytes = new byte[s.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2),
                    16);
        }
        return bytes;
    }

    public static byte[] decryptByPrivateKey(byte[] data, String privateKey, int length, boolean isBc)
            throws Exception {
        byte[] keyBytes = decryptBASE64(privateKey);
        assert keyBytes != null;
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher;
        if (isBc) {
            Security.addProvider(new BouncyCastleProvider());
            cipher = Cipher.getInstance(keyFactory.getAlgorithm(), "BC");
        } else {
            cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        }
        cipher.init(Cipher.DECRYPT_MODE, privateK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > length) {
                cache = cipher.doFinal(data, offSet, length);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * length;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    public static String decryptStr(String content, String privateKey) {
        try {
            byte[] decryptByte = RSACoder.decryptByPrivateKey(RSACoder.toBytes(content), privateKey, 256, false);
            return new String(decryptByte, CharsetUtil.CHARSET_UTF_8);
        } catch (Exception e) {
        }
        return null;
    }

    public static boolean verify(byte[] data, String publicKey, String sign, String algorithm)
            throws Exception {
        byte[] keyBytes = decryptBASE64(publicKey);
        assert keyBytes != null;
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance(algorithm);
        signature.initVerify(pubKey);
        signature.update(data);
        return signature.verify(toBytes(sign));
    }

    public static String getDate(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        String s = sdf.format(date);
        return s;
    }

    public static final String DATETIME_PATTERN = "yyyyMMddHHmmss";

    public static void main(String[] args) throws Exception {
        //singlepayment();
        //exemple();
        qrypaymentbalance();
    }

    private static void exemple() throws Exception {
        //请求地址
        String url = "https://mobl-test.chinaums.com/uisouterfront/uni/pay";
        //外部平台公钥
        //String pub = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlLo3bCW0RcYRh287rwnPk7zztBXqRMEA9IcLDcmV1gbANkZxARwXAchlmsXHzvqA0F9BATnAUYX5aF6uYp6dFN+UelRWJm9MwASLi8ORkRD97TL3OSYieLIaWo/B3wAUz3Dt7D9KpdDcF0fd06EmKFSG1OneNz1PbhqPyVFk4a4ZETwgfkFLhuxv5XBwut1GAu6VPaHL18eOuTBQTNrlma8MMRc9mNnQJo6B9TK2RiCuZzaCAgqoEFMuY+52ATwENLNG/9zxgtz8SmY15eJqvxXTDAg4QHDlnsHpHZuiHLK9lBVikXFFoJDYgQTtm3xMjLAUcK3u1yE62/R6Y0XIywIDAQAB";
        String pub = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmbGLSRAUfeqIly1XGT4z3CkC8VfOop51ND3wrgz7nO2atkgGPIfHhV21VerP3Q3dCg6H9oLjlDgte4nZFXSx74UKzws82RPX5e08KidVGrklaIk9B2ZhMSkGiaR3ZxO5LNUGGQ+vJHKslGTddcUwcrPLqjsT3ZeYf5QxqKxxiKoSMXrkLf6uDLX/4tyv5Z4kObjZbe3LqubKQitnqbDR+MAIxSyGo/TltLRw9UKNL3uAB2QOn5NrqKeZY/EpS9p3X6xaciBSndwQPP5Di97ius9n3U7FPiirhdDuECweM+jX956EzFg9Q3EeHZvtdew43q+ZwdhnnfVrADEsH9/T+QIDAQAB";
        //外部平台私钥
        //String pri = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCUujdsJbRFxhGHbzuvCc+TvPO0FepEwQD0hwsNyZXWBsA2RnEBHBcByGWaxcfO+oDQX0EBOcBRhfloXq5inp0U35R6VFYmb0zABIuLw5GREP3tMvc5JiJ4shpaj8HfABTPcO3sP0ql0NwXR93ToSYoVIbU6d43PU9uGo/JUWThrhkRPCB+QUuG7G/lcHC63UYC7pU9ocvXx465MFBM2uWZrwwxFz2Y2dAmjoH1MrZGIK5nNoICCqgQUy5j7nYBPAQ0s0b/3PGC3PxKZjXl4mq/FdMMCDhAcOWewekdm6Icsr2UFWKRcUWgkNiBBO2bfEyMsBRwre7XITrb9HpjRcjLAgMBAAECggEAHCmu+QGiw1ugUh8UFC8taXJsS3ui4uYRQjyYMUIs51xb5WstVuJ00NebtdUh4uW4oryG2K6Q5l8SPVtAdlhGsn8r5IY30gtdYzb5HbwowmmPS+1MtzurZ2OCbgeu1IV1a1qdExFhF0kXhCkNrldjnFt1NLgcZiVr9xN8isio67r7/Ae3sCQlEY5KDP9JRSALQ1/Sjss0zBLbwe6qmVj91kt7C6YqWC7/lLi6srFMUU8uWajCW4GwOXYN2rPB/+RsiLLqAUudz6zMvdohWZOHrQcVfOtcI/w+xChTZBqLmbJtnofn3ttbQVwVLcwNz7BnWt2R6QQ3+l2j1wg1YncogQKBgQDKzIpbNdx5aOssZrBS8fPA7pQQK8G2+RaE5ZSifa5tGvCfrjx4gNJ280P9FslwCK6dwAmUvaJXmSftPON+mCxTZAWTitqZn2eij5LSiyslOUFTHS778oeTpX9vKeDkRi+sw3LbD3z3WBut97kqVAHFb4oxAPBTsjmGL6jxmXr5awKBgQC7vl4bbjBRHNJczOetJQMXWQYxGVkDrji8fpwfLvCVD0gHnUZ+ADIYeUxDh5Cx/awpePHYrKnA6JQvcAjZDWuvY6XD34BcW+AIW4EDpODAFgH+4YFLgBz/8kPDwIfgsfUn0Q6n4PGpvDKGYIIwXj+COCb8gjidMeixEd5xLOFmIQKBgEYgMH+VwmVhOGEkKTilXcqLNTvaRaQFwhm2YY1GtHgZ5rbwwwxQT3a+a/YqWQGanvcBns6GPIrZ9Qp+EZSG/lzfq2X3j9urWWTHDNgtM4Atqj8ZSlPo66TMh6Ji8tc8xeORujexxV6qYvfnP2o5nlstVLXZQ0FN0cJq3Jqenf19AoGBAKJTPlrJMs1u9hN2tvllfv644jmhiO09vaB8d9AebbTzuXub6E8ZLDcs6VuZ4umCQ1C4WaLV5w/8B+PcIkpI6EqFBdYNcJZqeZHATBQygoCShrcxkvEMnAZQGXcvCEymkSkUAG/2dfwj1CuLVgUr+A1HL64ziW+gr2gp4wJHo7sBAoGATicJ2yHAmXgMlsLavaegWYqIYzEsX/xY82zIv+LKq5strWblxGJmgENZvUuKDdEaPDdKO75CiCTzG8/jyrR2DMlhCeVRC3cGwOPrSXTcVzk7V5agrd/m60/OorhGKsF8FW27qeTpZtV3pHuJybA7HEsIPQXvv2LsB/ADSo262Mw=";
        String pri = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCZsYtJEBR96oiXLVcZPjPcKQLxV86innU0PfCuDPuc7Zq2SAY8h8eFXbVV6s/dDd0KDof2guOUOC17idkVdLHvhQrPCzzZE9fl7TwqJ1UauSVoiT0HZmExKQaJpHdnE7ks1QYZD68kcqyUZN11xTBys8uqOxPdl5h/lDGorHGIqhIxeuQt/q4Mtf/i3K/lniQ5uNlt7cuq5spCK2epsNH4wAjFLIaj9OW0tHD1Qo0ve4AHZA6fk2uop5lj8SlL2ndfrFpyIFKd3BA8/kOL3uK6z2fdTsU+KKuF0O4QLB4z6Nf3noTMWD1DcR4dm+117Djer5nB2Ged9WsAMSwf39P5AgMBAAECggEABBSLc/e8MYkU0f2jSLFm70776+QWwWi3SBkmXvqLggOpVjJEjx4UMRFXL3YdyVq1Pe97ktLv/4b7xyI2XAxWbntP2YYM+h7dnhYtoRlc+CoG6RbuorgIN8XE7YnLHTaP9ZWctTTeQ5eTRxfD7Nzcr8jf7O+nU/xSsT1iEZ4tX/FIYShfI9rA+dRKqrg9sW+qYyIxcRNMGrC8EzeeL+x+AYrjbxzQq1r+D0C/8s27/22o05pnKQ2gKnwmwfUA7EWMGY7x0YR73mN1zJDfKgcKWh10qD2g1uOAOIQipxS+VAx4/q2o2D+7dA0hwOLr++Aoou+na8j/tfpdYKzwc16DMQKBgQDRE3TJ8OJU4fgb2FSC4PQ+hRIeBwuRRcvxVZDlv+oUgdfVIh3OrIVP66RKv8KhPmlZvjbuhYM9SgZB+cUhf4qAiz4GrBmI/uE4nhs8u8/njeiFsWBR7npuKk0iixq3even4W91PsozOCU1GoUKM/P+PF7HCPIlooB+NzNAK+ZQEQKBgQC8MBD7zaIe7N45hqyIEeiMZ5hIfDOpD+r4aysL/sD094B98OSh+zNrJzQho86h47Hwis1pKWpTUlDlOHAiwdoEF+e3Cpph+1Vgo14lfLsAheSUyRGMmRIAODRoe69UUvf8jE/n25mF35WUvJXB3nc03QR2Lpo5rCOGNNCokvYtaQKBgQCbA9DwtTAqfUxm4NNwIngVLrbLGrAh6t0WNznyjoNw5wBu3xe4l8NUCUPLxDf7M3oK9vRljwpKU+sl2Zmmh5jaS+MWMV3RbCDyyI8rTZkNdvLyxRvEQ4v0yFpehUKuzXZ3u7bW+FIU/cjggaQod3Ktinc/HUvkSYL5kdXm+2WM8QKBgAU+SZradePqsZ5ktDXuWc5frIyIeWACg4d8ZOymonWw17GqnpQszZf0ta0iRUWZdIHBPEvrzXyY1IwucGFniU2H5Prinr6QJCbXJm5g9UzkbiP/HjAOq8O5zSwEFjSBQ0uUFT3ejn5+ZkqInpuSOTwN1Gv+jGmC9FJu8klgHt/RAoGASX5QmaAe54I5cA6zvacAVrhJF5fLgvQJIw09J3X0G9zFQyxPMLgnOwMr5lvcyQAfOZj+KS7EPtjVyIjQbPycHdmh1pd8ZTRH0Fgx6UuM0WPQiup9kXhqsaRW9cD6TJDvqZ5nAv4Vfynj7li4/K2Lbhu/kT+NOlYraqVoLwjY8Ig=";
        //银商系统公钥
        String pubUms = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu13Ykr8Q4ACqnYMfLL5kgV2JsUC7TQEeWR70Zpulqq6JeujD6dCupnYnGhnMmePasgBZT0rIKGvoUEe5tMS1sfYo6dMqaAwcVfe4XOQaPSQs10XDSMB689+ImZmhECEBJkbKs7K+BBJXBOZGkgHBZsd4pn3vlF4E2yPTrfrcn9OEXZAKrUb/jZm6suzHoXSljqtHWwT7OwQoIX+Q/27gYA6PuGpFFmr4Xtc4a/AqIHeCC4TinbgboD8HqfL0ZoC4NG6Xm2KJ9wK66MbS7sYRiK+7pctZkZLxIJ47Ro5Psuxs4owTdtY7b1aHun9GoUT6Wm4mRO0asvBv0XKn05qn9wIDAQAB";

        //参数
        Random random = new Random();
        Map<String, Object> params = new HashMap<>();
        params.put("timestamp", getDate(new Date(), DATETIME_PATTERN));
        params.put("chnl", "zfb");
        params.put("batchNo", getDate(new Date(), DATETIME_PATTERN) + (100000000 + random.nextInt(99999999)));
        params.put("batchName", "测试批次名称");
        params.put("totalNum", 2);
        params.put("totalAmt", 200);
        params.put("remark", "测试批次备注");
        params.put("sysId", "UMS001");
        params.put("mchntNo", "898370658120117");
        Map<String, Object> paramSubs = new HashMap<>();
        paramSubs.put("orderNo", getDate(new Date(), DATETIME_PATTERN) + (100000000 + random.nextInt(99999999)));
        paramSubs.put("idenCode", "2088722030572914");
        paramSubs.put("idenType", "ALIPAY_USER_ID");
        paramSubs.put("idenName", "ocsvei7537");
        paramSubs.put("transAmt", 100);
        paramSubs.put("transRemark", "向ocsvei7537转款1元");

        Map<String, Object> paramSubs1 = new HashMap<>();
        paramSubs1.put("orderNo", getDate(new Date(), DATETIME_PATTERN) + (100000000 + random.nextInt(99999999)));
        paramSubs1.put("idenCode", "2088722030572914");
        paramSubs1.put("idenType", "ALIPAY_USER_ID");
        paramSubs1.put("idenName", "ocsvei7537");
        paramSubs1.put("transAmt", 100);
        paramSubs1.put("transRemark", "向ocsvei7537转款1元");

        List<Map<String, Object>> datas = new ArrayList<>();
        datas.add(paramSubs);
        datas.add(paramSubs1);
        params.put("data", datas);

        //生成sign标记
        //先进行参数排序
        String str = generateSortStr(params, true);
        System.out.println(str);
        //参数加密
        String sign = sign(str.getBytes(CharsetUtil.CHARSET_UTF_8), pri, RSACoder.ALGORITHM_SHA256WITHRSA);
        byte[] data = str.getBytes(CharsetUtil.CHARSET_UTF_8);
        System.out.println(RSACoder.verify(data, pub, sign, RSACoder.ALGORITHM_SHA256WITHRSA));

        params.put("sign", sign);
        System.out.println(sign);
        //参数加密
        byte[] encryptBytes = RSACoder.encryptByPublicKey(JSONUtil.toJsonStr(params).getBytes(CharsetUtil.CHARSET_UTF_8), pubUms, 245, false);
        String enc = HexUtil.encodeHexStr(encryptBytes);
        System.out.println(enc);

        Map<String, String> map = new HashMap<>();
        map.put("content", enc);
        String resp = OpenHttpClient.request_https(url, JSONUtil.toJsonStr(map));
        System.out.println(resp);

        //返回参数解密
        String respDec = RSACoder.decryptStr(resp, pri);
        System.out.println(respDec);
        Map<String, Object> maps = JSONUtil.toBean(respDec, Map.class);
        String encStr = RSACoder.generateSortStr(maps, true);
        System.out.println(encStr);
        byte[] data1 = encStr.getBytes(CharsetUtil.CHARSET_UTF_8);
        System.out.println(RSACoder.verify(data1, pubUms, String.valueOf(maps.get("sign")), RSACoder.ALGORITHM_SHA256WITHRSA));
    }

    //单笔代付
    public static String singlepayment() throws Exception {
        //请求地址
        String url = "https://mobl-test.chinaums.com/uisouterfront/singlepayment/process";
        //外部平台公钥
        String pub = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlLo3bCW0RcYRh287rwnPk7zztBXqRMEA9IcLDcmV1gbANkZxARwXAchlmsXHzvqA0F9BATnAUYX5aF6uYp6dFN+UelRWJm9MwASLi8ORkRD97TL3OSYieLIaWo/B3wAUz3Dt7D9KpdDcF0fd06EmKFSG1OneNz1PbhqPyVFk4a4ZETwgfkFLhuxv5XBwut1GAu6VPaHL18eOuTBQTNrlma8MMRc9mNnQJo6B9TK2RiCuZzaCAgqoEFMuY+52ATwENLNG/9zxgtz8SmY15eJqvxXTDAg4QHDlnsHpHZuiHLK9lBVikXFFoJDYgQTtm3xMjLAUcK3u1yE62/R6Y0XIywIDAQAB";
        //外部平台私钥
        String pri = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCUujdsJbRFxhGHbzuvCc+TvPO0FepEwQD0hwsNyZXWBsA2RnEBHBcByGWaxcfO+oDQX0EBOcBRhfloXq5inp0U35R6VFYmb0zABIuLw5GREP3tMvc5JiJ4shpaj8HfABTPcO3sP0ql0NwXR93ToSYoVIbU6d43PU9uGo/JUWThrhkRPCB+QUuG7G/lcHC63UYC7pU9ocvXx465MFBM2uWZrwwxFz2Y2dAmjoH1MrZGIK5nNoICCqgQUy5j7nYBPAQ0s0b/3PGC3PxKZjXl4mq/FdMMCDhAcOWewekdm6Icsr2UFWKRcUWgkNiBBO2bfEyMsBRwre7XITrb9HpjRcjLAgMBAAECggEAHCmu+QGiw1ugUh8UFC8taXJsS3ui4uYRQjyYMUIs51xb5WstVuJ00NebtdUh4uW4oryG2K6Q5l8SPVtAdlhGsn8r5IY30gtdYzb5HbwowmmPS+1MtzurZ2OCbgeu1IV1a1qdExFhF0kXhCkNrldjnFt1NLgcZiVr9xN8isio67r7/Ae3sCQlEY5KDP9JRSALQ1/Sjss0zBLbwe6qmVj91kt7C6YqWC7/lLi6srFMUU8uWajCW4GwOXYN2rPB/+RsiLLqAUudz6zMvdohWZOHrQcVfOtcI/w+xChTZBqLmbJtnofn3ttbQVwVLcwNz7BnWt2R6QQ3+l2j1wg1YncogQKBgQDKzIpbNdx5aOssZrBS8fPA7pQQK8G2+RaE5ZSifa5tGvCfrjx4gNJ280P9FslwCK6dwAmUvaJXmSftPON+mCxTZAWTitqZn2eij5LSiyslOUFTHS778oeTpX9vKeDkRi+sw3LbD3z3WBut97kqVAHFb4oxAPBTsjmGL6jxmXr5awKBgQC7vl4bbjBRHNJczOetJQMXWQYxGVkDrji8fpwfLvCVD0gHnUZ+ADIYeUxDh5Cx/awpePHYrKnA6JQvcAjZDWuvY6XD34BcW+AIW4EDpODAFgH+4YFLgBz/8kPDwIfgsfUn0Q6n4PGpvDKGYIIwXj+COCb8gjidMeixEd5xLOFmIQKBgEYgMH+VwmVhOGEkKTilXcqLNTvaRaQFwhm2YY1GtHgZ5rbwwwxQT3a+a/YqWQGanvcBns6GPIrZ9Qp+EZSG/lzfq2X3j9urWWTHDNgtM4Atqj8ZSlPo66TMh6Ji8tc8xeORujexxV6qYvfnP2o5nlstVLXZQ0FN0cJq3Jqenf19AoGBAKJTPlrJMs1u9hN2tvllfv644jmhiO09vaB8d9AebbTzuXub6E8ZLDcs6VuZ4umCQ1C4WaLV5w/8B+PcIkpI6EqFBdYNcJZqeZHATBQygoCShrcxkvEMnAZQGXcvCEymkSkUAG/2dfwj1CuLVgUr+A1HL64ziW+gr2gp4wJHo7sBAoGATicJ2yHAmXgMlsLavaegWYqIYzEsX/xY82zIv+LKq5strWblxGJmgENZvUuKDdEaPDdKO75CiCTzG8/jyrR2DMlhCeVRC3cGwOPrSXTcVzk7V5agrd/m60/OorhGKsF8FW27qeTpZtV3pHuJybA7HEsIPQXvv2LsB/ADSo262Mw=";
        //银商系统公钥
        String pubUms = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu13Ykr8Q4ACqnYMfLL5kgV2JsUC7TQEeWR70Zpulqq6JeujD6dCupnYnGhnMmePasgBZT0rIKGvoUEe5tMS1sfYo6dMqaAwcVfe4XOQaPSQs10XDSMB689+ImZmhECEBJkbKs7K+BBJXBOZGkgHBZsd4pn3vlF4E2yPTrfrcn9OEXZAKrUb/jZm6suzHoXSljqtHWwT7OwQoIX+Q/27gYA6PuGpFFmr4Xtc4a/AqIHeCC4TinbgboD8HqfL0ZoC4NG6Xm2KJ9wK66MbS7sYRiK+7pctZkZLxIJ47Ro5Psuxs4owTdtY7b1aHun9GoUT6Wm4mRO0asvBv0XKn05qn9wIDAQAB";

        //参数
        Random random = new Random();
        Map<String, Object> params = new HashMap<>();
        //时间戳
        params.put("timestamp", getDate(new Date(), DATETIME_PATTERN));
        //系统id
        params.put("sysId", "UMS001");
        //代付商户
        params.put("mchntNo", "898370658120117");
        //系统单号
        params.put(" sysOrderld", getDate(new Date(), DATETIME_PATTERN) + (100000000 + random.nextInt(99999999)));
        //代付金额,单位分
        params.put("payAmt", "10000");
        //收款账号
        params.put("revAcctNo", "234234235445");
        //收款人姓名
        params.put("revAcctName", "张三");

        //生成sign标记
        //先进行参数排序
        String str = generateSortStr(params, true);
        System.out.println(str);
        //参数加密
        String sign = sign(str.getBytes(CharsetUtil.CHARSET_UTF_8), pri, RSACoder.ALGORITHM_SHA256WITHRSA);
        byte[] data = str.getBytes(CharsetUtil.CHARSET_UTF_8);
        System.out.println(RSACoder.verify(data, pub, sign, RSACoder.ALGORITHM_SHA256WITHRSA));

        params.put("sign", sign);
        System.out.println(sign);
        //参数加密
        byte[] encryptBytes = RSACoder.encryptByPublicKey(JSONUtil.toJsonStr(params).getBytes(CharsetUtil.CHARSET_UTF_8), pubUms, 245, false);
        String enc = HexUtil.encodeHexStr(encryptBytes);
        System.out.println(enc);

        Map<String, String> map = new HashMap<>();
        map.put("content", enc);
        //String resp = OpenHttpClient.request_https(url, JSONUtil.toJsonStr(map));
        HttpResponse response = HttpRequest.post(url).formStr(map).execute();
        System.out.println(response);

        //返回参数解密
        String respDec = RSACoder.decryptStr(response.body(), pri);
        System.out.println(respDec);
        Map<String, Object> maps = JSONUtil.toBean(respDec, Map.class);
        String encStr = RSACoder.generateSortStr(maps, true);
        System.out.println(encStr);
        byte[] data1 = encStr.getBytes(CharsetUtil.CHARSET_UTF_8);
        System.out.println(RSACoder.verify(data1, pubUms, String.valueOf(maps.get("sign")), RSACoder.ALGORITHM_SHA256WITHRSA));
        return "";
    }

    /**
     * 余额查询
     *
     * @return {@link String }
     * @throws Exception 异常
     */
    public static String qrypaymentbalance() throws Exception {
        //请求地址
        String url = "https://managefree.chinaums.com/uisouterfront/qrypaymentbalance/process";
        //外部平台公钥
        String pub = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3CvmnSuqASLQGiZQvsZheIYqNmLjQ/r7zbJDnbuN8jLBeiKabgkLJ4fDcR3cFO45KRmLaMbWozyyEKPHFN/7UpXwAOeJGUXgmdVr5czPOb+KBRNdACC/wOuqJ+L0d4nMRQAEcr6bujTZWLQaIeVb0nMkORTHug+VglJi6+sdLiUQTcm06BbRSEaeYzLYwupChB4iJctWQBe3u09dLe2uoZ0hmG/nZG5sXaz44IoXBE+rAE8ylZwqeGTI/UoO4+uvmuvZ7OCYZfcCjQ7guZg4eZ5G4DN6fyHoFmFU00NcWGAcs8EBQ/g0qsB7729oO5q3Xbt7pq2BZyfxurjiUM3TZwIDAQAB";
        //外部平台私钥
        String pri = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDcK+adK6oBItAaJlC+xmF4hio2YuND+vvNskOdu43yMsF6IppuCQsnh8NxHdwU7jkpGYtoxtajPLIQo8cU3/tSlfAA54kZReCZ1WvlzM85v4oFE10AIL/A66on4vR3icxFAARyvpu6NNlYtBoh5VvScyQ5FMe6D5WCUmLr6x0uJRBNybToFtFIRp5jMtjC6kKEHiIly1ZAF7e7T10t7a6hnSGYb+dkbmxdrPjgihcET6sATzKVnCp4ZMj9Sg7j66+a69ns4Jhl9wKNDuC5mDh5nkbgM3p/IegWYVTTQ1xYYByzwQFD+DSqwHvvb2g7mrddu3umrYFnJ/G6uOJQzdNnAgMBAAECggEAOOleLL1nLfD+Quwpjg7AjkN78OAB6AYeBa8xPDoJeJQ3H+eG7K+IwxicZAZ4Z66mduHD//r562saiiOTp+k30UKxrcIr1a0S4CDjSZz16fMBbctyDEDq4CbqrnHDiIzFkQZun+x2W50im4O+h4l+gTlDIUAmWomBt5StPldhjRYL0ZtAdQ3RMOkYIGzoG97AH7lNqA5s0ANT0hqglia+1VBs9Rqs1Afaii+a4Jam4JfCBbwCLNHx2kCiPoO6Di8V7DzRj+P9VOZcYZMv6WtGGoEtpcwHI/VGFEnPYHfKEnGdNEPA5gmQNHGclJ9efuWgFd8UvE15syB59XlTZRwFAQKBgQDvSIUqDZ/awpalSGIF8QY5HqsKbLqCfBlsR+rmJyReU+exzWjHY6xlrqBYjUClta5Hr/iwub+aBT2rUZKU5o3oElJZgzb0V7nRKs73z+59WPsWMf8wI3EcQJ0e3Qyn41lL8WagsysLu+OIIGnGUiObg/CWynwT+kY2EpGJ4el6ZwKBgQDrjZMIHBkpLkjT1sZT8f9rUhHlW5F9hiOT7XVGGw3BP2LwD5SC4DRcOwjVD/LaXh4twg2YOB3lq1p8/FShNqkGzxtzRRtM3Nnd7ikRk6bhzyxq1ppPgu/hKB6RnDDRe7QEIh/JYEc8eO8dxTcbP1nSkvgPsECo9sQVIlHupvM/AQKBgHs22bNs7prERrR3kFpE4ZJ6M1Mb5/KXGrRCWDgJgdW82PsardC2h6iYgmL24YozArpRZ/sAuyQBfN8CEzvveLU+8f677Ylmvv1xUMAU51bOggTM2/4a0fzdXMruwryU+n97oAAyIoFZT/Hh1vXTiBhlmXbcb4YOAyeG6kCY/xQTAoGBAIn+5NZpb6wae3vvZT0klthOukE+Bdwdy5YMFRo/Gy3Nbq7o0b5ijwpBY4k+0K1xWgjAmKpGpe05F8gFI6dWmGtuxcwf/kBnWhOUROcRM0Ey1/i3RKu0L8gectonQMpYyDtrqmeVSeZ5isxMD16dHIgqpby7KwZRmsou0wUXNYYBAoGBAMsoHomyJ50NQNE2HfnuAqVYeXosBNwl9fmFWodbrQgxVBTVBBMydJg7sAd+aDSPz86QSy+dVO0ZCdB7jnvN72OOV0yfXiSqkdPgkXl5UAJyhcNAnL1cPldKyRx7PEDDPbb3nCL6Im018Rdyk8DrJJhsQHGlEiMUaD9PHdJcY/go";
        //银商系统公钥
        String pubUms = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhTzN8wxdXYr+/+t8iX0mlol8wFy+0pGtxnyB6PjyrIRjGHrZJA7grZPvy7MOK6PqihqTZh6SO7tX9StxVmTQo+PuibAY/p2i08UxkIBUcucHVvHN8gkM3GBFBqD0uJgUc03cerEI7gNeaKYfCVs0/hMo6CKbdXVKqaE987kXYK209uFcte+Y8YofQ2AYamImpzSf7pXomAu+8D98HIOs5bKITHTk30vPdNhrQdpDRO1TuX0x8bwhCykcwAEdB/Z9YGXkLU5S3QJY2qvCZJY08YdNqIpbDqifSRvOg0sqeKFXPfI2M0GsOh6PArTEmh0QHxDht9xjPPt11aVgh8kgkQIDAQAB";

        //参数
        Random random = new Random();
        Map<String, Object> params = new HashMap<>();
        //时间戳
        params.put("timestamp", getDate(new Date(), DATETIME_PATTERN));
        //系统id
        params.put("sysId", "10215");
        //代付商户
        params.put("mchntNo", "89813057399Y005");

        //生成sign标记
        //先进行参数排序
        String str = generateSortStr(params, true);
        System.out.println(str);
        //参数加密
        String sign = sign(str.getBytes(CharsetUtil.CHARSET_UTF_8), pri, RSACoder.ALGORITHM_SHA256WITHRSA);
        byte[] data = str.getBytes(CharsetUtil.CHARSET_UTF_8);
        System.out.println(RSACoder.verify(data, pub, sign, RSACoder.ALGORITHM_SHA256WITHRSA));

        params.put("sign", sign);
        System.out.println(sign);
        //参数加密
        byte[] encryptBytes = RSACoder.encryptByPublicKey(JSONUtil.toJsonStr(params).getBytes(CharsetUtil.CHARSET_UTF_8), pubUms, 245, false);
        String enc = HexUtil.encodeHexStr(encryptBytes);
        System.out.println(enc);

        Map<String, String> map = new HashMap<>();
        map.put("content", enc);
        //String resp = OpenHttpClient.request_https(url, JSONUtil.toJsonStr(map));
        HttpResponse response = HttpRequest.post(url).formStr(map).execute();
        System.out.println(response);

        //返回参数解密
        String respDec = RSACoder.decryptStr(response.body(), pri);
        System.out.println(respDec);
        Map<String, Object> maps = JSONUtil.toBean(respDec, Map.class);
        String encStr = RSACoder.generateSortStr(maps, true);
        System.out.println(encStr);
        byte[] data1 = encStr.getBytes(CharsetUtil.CHARSET_UTF_8);
        System.out.println(RSACoder.verify(data1, pubUms, String.valueOf(maps.get("sign")), RSACoder.ALGORITHM_SHA256WITHRSA));
        return "";
    }


}
